package main

import (
	"fmt"
	"io/ioutil"
	"os"
	"strconv"
	"strings"
)

func main() {
	argCount := len(os.Args)
	if argCount < 4 {
		fmt.Println("Argument format: project_name service_name service_port(example: openresty-chat account-service 80)")
		os.Exit(-1)
	}
	projectName := os.Args[1]
	serviceName := os.Args[2]
	servicePort, err := strconv.Atoi(os.Args[3])
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}

	serviceDirectoryPath, confDirectoryPath, srcDirectoryPath := createMustDirectory(projectName, serviceName)
	createNginxConfFile(projectName, serviceName, servicePort, confDirectoryPath)
	createAppConfFile(projectName, serviceName, servicePort, confDirectoryPath)
	createMainLua(projectName, serviceName, servicePort, srcDirectoryPath)

	createScriptFile(projectName, serviceName, servicePort, "./template/run.sh.template", "run.sh", serviceDirectoryPath)
	createScriptFile(projectName, serviceName, servicePort, "./template/start.sh.template", "start.sh", serviceDirectoryPath)
	createScriptFile(projectName, serviceName, servicePort, "./template/stop.sh.template", "stop.sh", serviceDirectoryPath)
	createScriptFile(projectName, serviceName, servicePort, "./template/restart.sh.template", "restart.sh", serviceDirectoryPath)

	fmt.Println("finished!")
}

func createScriptFile(projectName string, serviceName string, servicePort int, templatePath string, scriptName string, serviceDirectoryPath string) {
	filePath := fmt.Sprintf("%s/%s", serviceDirectoryPath, scriptName)
	createFile(projectName, serviceName, servicePort, templatePath, filePath)
}

func createNginxConfFile(projectName string, serviceName string, servicePort int, confDirectoryPath string) {
	filePath := fmt.Sprintf("%s/%s-nginx.conf", confDirectoryPath, serviceName)
	createFile(projectName, serviceName, servicePort, "./template/nginx.conf.template", filePath)
}

func createAppConfFile(projectName string, serviceName string, servicePort int, confDirectoryPath string) {
	filePath := fmt.Sprintf("%s/%s-app.json", confDirectoryPath, serviceName)
	createFile(projectName, serviceName, servicePort, "./template/app.json.template", filePath)
}

func createMainLua(projectName string, serviceName string, servicePort int, srcDirectoryPath string) {
	filePath := fmt.Sprintf("%s/main.lua", srcDirectoryPath)
	createFile(projectName, serviceName, servicePort, "./template/main.lua.template", filePath)
}

func createFile(projectName string, serviceName string, servicePort int, templatePath string, filePath string) {
	templateContent := readFileContent(templatePath)
	fileContent := replaceTemplateContent(templateContent, projectName, serviceName, servicePort)
	writeFileContent(filePath, fileContent)
	fmt.Println(fileContent)
	fmt.Println()
}

func createMustDirectory(projectName string, serviceName string) (serviceDirectoryPath string, confDirectoryPath string, srcDirectoryPath string) {
	serviceDirectoryPath = fmt.Sprintf("./%s/%s", projectName, serviceName)
	confDirectoryPath = fmt.Sprintf("%s/conf", serviceDirectoryPath)
	createDirectory(confDirectoryPath)
	srcDirectoryPath = fmt.Sprintf("%s/src", serviceDirectoryPath)
	createDirectory(srcDirectoryPath)
	commonLibPath := fmt.Sprintf("./%s/common/lib", projectName)
	createDirectory(commonLibPath)
	commonLogicPath := fmt.Sprintf("./%s/common/logic", projectName)
	createDirectory(commonLogicPath)
	fmt.Println()
	return
}

func createDirectory(path string) {
	err := os.MkdirAll(path, os.ModePerm)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
	fmt.Println("createDirectory:", path)
}

func readFileContent(filename string) string {
	reader, err := ioutil.ReadFile(filename)
	if err != nil {
		fmt.Println("err: ", err)
		return ""
	}
	result := string(reader)
	return result
}

func writeFileContent(filename string, content string) {
	err := ioutil.WriteFile(filename, []byte(content), 0777)
	if err != nil {
		fmt.Println(err)
		os.Exit(-1)
	}
	fmt.Println("createFile:", filename)
}

func replaceTemplateContent(templateContent string, projectName string, serviceName string, servicePort int) string {
	result := templateContent
	result = strings.Replace(result, "${service_name}", serviceName, -1)
	result = strings.Replace(result, "${project_name}", projectName, -1)
	result = strings.Replace(result, "${service_port}", strconv.Itoa(servicePort), -1)
	result = strings.Replace(result, "\r\n", "\n", -1)
	return result
}
